<template></template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount } from 'vue'
import {
  PoseLandmarker,
  FilesetResolver,
} from 'https://cdn.skypack.dev/@mediapipe/tasks-vision@0.10.0'
import BodyAction = API.BodyAction
import { getHrBodyActionUsingPost } from '@/api/hrInterviewController'
import { getBodyActionUsingPost } from '@/api/tecInterviewController'

const props = defineProps<{
  videoRef: HTMLVideoElement | null
  interviewType: string
}>()

// 定义emit
const emit = defineEmits(['body-action-detected'])

let poseLandmarker: PoseLandmarker | undefined // 躯干模型
let runningMode: 'VIDEO'
let bodyDetectionTimer: number | null = null // 驱干检测器定时器
const EAR_TOUCH_THRESHOLD = 0.16 // 触摸阈值
const NOSE_TOUCH_THRESHOLD = 0.16 // 触摸阈值
const CANCEL_TOUCH_THRESHOLD = 0.7 // 取消触摸阈值
const HOLD_TIME_MS = 300 // 触摸时间阈值

let earCount = 0 // 摸耳朵计数器
let noseCount = 0 // 摸鼻子计数器

let isTouchingLeftEar = false // 摸左耳朵状态
let leftEarTouchStart = 0
let isStartLeftEar = false

let isTouchingRightEar = false // 摸右耳朵状态
let rightEarTouchStart = 0
let isStartRightEar = false

let isTouchingLeftNose = false // 左手摸鼻子状态
let leftNoseTouchStart = 0 //
let isStartLeftNose = false

let isTouchingRightNose = false // 右手摸鼻子状态
let rightNoseTouchStart = 0
let isStartRightNose = false

/**
 * 初始化躯干模型
 */
async function initPoseModel() {
  const vision = await FilesetResolver.forVisionTasks(
    'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm'
  )
  poseLandmarker = await PoseLandmarker.createFromOptions(vision, {
    baseOptions: {
      modelAssetPath:
        'https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task',
      delegate: 'GPU',
    },
    runningMode: runningMode,
    numPoses: 1,
  })
  console.log('✅ 躯干模型加载成功')
}

/**
 * 开启肢体检测
 */
async function startBodyDetection() {
  if (!poseLandmarker || !props.videoRef) return

  // 重置触摸状态，但保持计数不变
  isTouchingLeftEar = false
  leftEarTouchStart = 0
  isStartLeftEar = false

  isTouchingRightEar = false
  rightEarTouchStart = 0
  isStartRightEar = false

  isTouchingLeftNose = false
  leftNoseTouchStart = 0
  isStartLeftNose = false

  isTouchingRightNose = false
  rightNoseTouchStart = 0
  isStartRightNose = false

  await poseLandmarker.setOptions({ runningMode: 'VIDEO' })

  bodyDetectionTimer = window.setInterval(async () => {
    const startTimeMs = performance.now()

    //调用模型检测
    poseLandmarker.detectForVideo(props.videoRef, startTimeMs, (result) => {
      if (result.landmarks.length > 0) {
        const pose = result.landmarks[0]

        // --- 获取相关关键点 ---
        const nose = pose[0] //鼻子
        const leftEar = pose[7] //左耳
        const rightEar = pose[8] //右耳
        const leftIndex = pose[19] //左手指
        const rightIndex = pose[20] //右手指

        // --- 计算欧几里得距离 ---
        const dist = (a: any, b: any) => {
          return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)
        }

        const leftHandsToNose = dist(nose, leftIndex) //  计算左手和鼻子的距离（是否摸鼻子）
        const rightHandsToNose = dist(nose, rightIndex) //计算右手和鼻子的距离（是否摸鼻子）
        const leftHandsToEar = dist(leftEar, leftIndex) //计算左手和耳朵的距离（是否摸耳朵）
        const rightHandsToEar = dist(rightEar, rightIndex) //计算右手和耳朵的距离（是否摸耳朵）

        const now = performance.now() // 当前时间（ms）

        // 判断哪个动作更明显 - 比较距离确定手更靠近哪个部位
        const isLeftHandCloserToNose = leftHandsToNose < leftHandsToEar
        const isRightHandCloserToNose = rightHandsToNose < rightHandsToEar

        // 左手摸鼻子 - 只有当左手更靠近鼻子而不是耳朵时才检测
        if (leftHandsToNose < NOSE_TOUCH_THRESHOLD && isLeftHandCloserToNose) {
          if (!isStartLeftNose) {
            leftNoseTouchStart = now
            isStartLeftNose = true
          } else if (now - leftNoseTouchStart > HOLD_TIME_MS && !isTouchingLeftNose) {
            isTouchingLeftNose = true
            noseCount++
            console.log('左手摸鼻子：' + noseCount)
            // 触发事件，更加稳定的方式
            emit('body-action-detected', { bodyAction: 'nose', index: 1 })
          }
        } else if (leftHandsToNose > CANCEL_TOUCH_THRESHOLD) {
          // 只有在之前检测到动作的情况下才重置状态
          if (isStartLeftNose) {
            isStartLeftNose = false
            isTouchingLeftNose = false
          }
        }

        // 右手摸鼻子 - 同样的逻辑，只有当右手更靠近鼻子而不是耳朵时才检测
        if (rightHandsToNose < NOSE_TOUCH_THRESHOLD && isRightHandCloserToNose) {
          if (!isStartRightNose) {
            rightNoseTouchStart = now
            isStartRightNose = true
          } else if (now - rightNoseTouchStart > HOLD_TIME_MS && !isTouchingRightNose) {
            isTouchingRightNose = true
            noseCount++
            console.log('右手摸鼻子：' + noseCount)
            emit('body-action-detected', { bodyAction: 'nose', index: 1 })
          }
        } else if (rightHandsToNose > CANCEL_TOUCH_THRESHOLD) {
          if (isStartRightNose) {
            isStartRightNose = false
            isTouchingRightNose = false
          }
        }

        // 左手摸左耳 - 只有当左手更靠近耳朵而不是鼻子时才检测
        if (leftHandsToEar < EAR_TOUCH_THRESHOLD && !isLeftHandCloserToNose) {
          if (!isStartLeftEar) {
            leftEarTouchStart = now
            isStartLeftEar = true
          } else if (now - leftEarTouchStart > HOLD_TIME_MS && !isTouchingLeftEar) {
            isTouchingLeftEar = true
            earCount++
            console.log('左手摸左耳：' + earCount)
            emit('body-action-detected', { bodyAction: 'ear', index: 0 })
          }
        } else if (leftHandsToEar > CANCEL_TOUCH_THRESHOLD) {
          if (isStartLeftEar) {
            isStartLeftEar = false
            isTouchingLeftEar = false
          }
        }

        // 右手摸右耳 - 只有当右手更靠近耳朵而不是鼻子时才检测
        if (rightHandsToEar < EAR_TOUCH_THRESHOLD && !isRightHandCloserToNose) {
          if (!isStartRightEar) {
            rightEarTouchStart = now
            isStartRightEar = true
          } else if (now - rightEarTouchStart > HOLD_TIME_MS && !isTouchingRightEar) {
            isTouchingRightEar = true
            earCount++
            console.log('右手摸右耳：' + earCount)
            emit('body-action-detected', { bodyAction: 'ear', index: 0 })
          }
        } else if (rightHandsToEar > CANCEL_TOUCH_THRESHOLD) {
          if (isStartRightEar) {
            isStartRightEar = false
            isTouchingRightEar = false
          }
        }
      }
    })
  }, 100) // 每 100ms 检测一次
}

/**
 * 关闭肢体检测
 */
function stopBodyDetection() {
  //关闭定时检测器
  if (bodyDetectionTimer) {
    clearInterval(bodyDetectionTimer)
    bodyDetectionTimer = null
  }

  //发送肢体检测结果
  sendBodyDetection([
    {
      bodyAction: 'ear',
      counter: earCount as any,
    },
    {
      bodyAction: 'nose',
      counter: noseCount as any,
    },
  ])

  // 重置状态变量 - 但不清除计数器，由TecInterview组件管理
  isTouchingLeftEar = false
  leftEarTouchStart = 0
  isStartLeftEar = false
  isTouchingRightEar = false
  rightEarTouchStart = 0
  isStartRightEar = false
  isTouchingLeftNose = false
  leftNoseTouchStart = 0
  isStartLeftNose = false
  isTouchingRightNose = false
  rightNoseTouchStart = 0
  isStartRightNose = false

  // earCount = 0  // 由TecInterview管理
  // noseCount = 0 // 由TecInterview管理

  console.log('✅ 肢体检测已关闭，动作计数已发送')
}

/**
 * 发送肢体检测
 */
const sendBodyDetection = async (bodyActionList?: BodyAction[]) => {
  //发送数据
  if (props.interviewType === '0') {
   //技术面
    await getBodyActionUsingPost({
      bodyActionList: bodyActionList,
    })
  } else {
    //hr面
    await getHrBodyActionUsingPost({
      bodyActionList: bodyActionList,
    })
  }
}

/**
 * 重置所有计数器但不重置检测状态
 */
const resetCounts = () => {
  console.log('重置BodyDetection中的所有计数器')
  // 重置摸耳朵计数器
  earCount = 0
  // 重置摸鼻子计数器
  noseCount = 0

  // 重置触摸状态
  isTouchingLeftEar = false
  isTouchingRightEar = false
  isTouchingLeftNose = false
  isTouchingRightNose = false

  // 重置开始状态
  isStartLeftEar = false
  isStartRightEar = false
  isStartLeftNose = false
  isStartRightNose = false

  // 重置计时器
  leftEarTouchStart = 0
  rightEarTouchStart = 0
  leftNoseTouchStart = 0
  rightNoseTouchStart = 0
}

onMounted(() => {
  // 初始化躯干模型
  initPoseModel()
})

onBeforeUnmount(() => {
  //关闭躯干检测
  stopBodyDetection()
})
// ✅ 暴露方法给父组件
defineExpose({
  startBodyDetection,
  stopBodyDetection,
  resetCounts,
})
</script>

<style scoped></style>
